#include "timer.h"

/** Program timer (0,1,2) with mode
 */
void timer_init(int timer, int mode) {
	// Preparar o modo
	int ntimer = timer;
	/*switch(timer) {
		case 0: ntimer = TIMER_0; break;
		case 1: return;
		case 2: ntimer = TIMER_2; break;
		default: return;
	}*/
	outportb(TIMER_CTRL, (ntimer << 6) | mode);	
}

/** Load timer (0,1,2) with value
 */
void timer_load(int timer, int value) {
	// Escrever os valores LSB e MSB
	int ntimer;
	switch(timer) {
		case 0: ntimer = TIMER_0; break;
		case 1: return;
		case 2: ntimer = TIMER_2; break;
		default: return;
	}
	outportb(ntimer, LSB(value) );
	outportb(ntimer, MSB(value) );
}

/** Wait mili miliseconds, indirectly counting T0 interrupts
*/
void mili_sleep(int mili) {
	int time0 = time_tick + mili;
	while ( time_tick < time0 ) ;
}

/** wait secs seconds, indirectly counting T0 interrupts
 */
void sec_sleep(int secs) {
	mili_sleep(secs * 1000);
}

void setTimer(int* timer, int mili)
{
	*timer = time_tick + mili;
}

Bool getTimerReached(int* timer)
{
	if(*timer != 0 && time_tick >= *timer)
	{
		*timer = 0;
		return true;
	}
	else
		return false;
}

void initTimer0( void (*t0_handler)(void) ) {
	timer_init(0, LCOM_MODE);
	timer_load(0, (int) (TIMER_CLK/1193.181) ); // Interrupção a cada 1 mili-segundo
	install_asm_irq_handler(T0_IRQ, t0_handler, &timer0_old_irq);
	enable_irq(T0_IRQ);
}

void endTimer0() {
	//disable_irq(T0_IRQ);
	reinstall_asm_irq_handler(T0_IRQ, &timer0_old_irq);
}

void handler_timer0() {
	time_tick++;
	if (time_tick%TICKS_PER_STEP == 0) {
		novo_step = true;
	}
	outportb(PIC1_CMD, EOI);
}
